/*
 * @Author       : Bing Chen chenbing@iocharger.com
 * @Date         : 2025-01-21 16:09:28
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 13:06:12
 * @FilePath     : \openchaoji-corelib\x86\secc\app_compile_secc_x86.c
 * @Description  :
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "../../secc/include/OpenChaoJi_secc.h"

#include "../app_hal_x86.h"
#include "secc_x86.h"

/* X86 GCC 测试程序 */

static struct OpenChaoJi_secc_context * s_secc_context[HAL_SIMU_CONNECTOR_NUM] = {NULL, NULL};
static struct OpenChaoJi_secc_context_create_info s_secc_create_info[HAL_SIMU_CONNECTOR_NUM];
static struct OpenChaoJi_secc_app_start_parameter s_secc_app_parameter[HAL_SIMU_CONNECTOR_NUM];
static struct OpenChaoJi_secc_context_status s_secc_app_status[HAL_SIMU_CONNECTOR_NUM];

static void secc_app_one_init(int idx)
{
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
    if (idx == 0)
    {
        memset(&s_secc_create_info[idx], 0x00, sizeof(s_secc_create_info[idx]));

        s_secc_create_info[idx].tag = 0;
        s_secc_create_info[idx].hal_handle = secc_hal_one_handle(idx);
        s_secc_create_info[idx].secc_gbt27930_type = OPENCHAOJI_SECC_GBT27930_TYPE_A;

        s_secc_create_info[idx].pilot.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].pilot.hal_handle = s_secc_create_info[idx].hal_handle;
        s_secc_create_info[idx].pilot.secc_gbt27930_type = s_secc_create_info[idx].secc_gbt27930_type;

        s_secc_create_info[idx].session.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.hal_handle = s_secc_create_info[idx].hal_handle;
        s_secc_create_info[idx].session.secc_gbt27930_type = s_secc_create_info[idx].secc_gbt27930_type;

        s_secc_create_info[idx].session.gbt27930_info.gbt27930_a.dummy = 0;

        s_secc_create_info[idx].session.data_buff.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.data_buff.recv_capacity = 4;

        s_secc_create_info[idx].session.linkage.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.linkage.gbt27930_info.gbt27930_a.dummy = 0;
        s_secc_create_info[idx].session.linkage.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.linkage.hal_handle = s_secc_create_info[idx].hal_handle;
        s_secc_create_info[idx].session.linkage.secc_gbt27930_type = s_secc_create_info[idx].secc_gbt27930_type;

        memset(&s_secc_app_parameter[idx], 0x00, sizeof(s_secc_app_parameter[idx]));
        s_secc_app_parameter[idx].parameter_max_charging_volt = 7550;
        s_secc_app_parameter[idx].parameter_min_charging_volt = 2600;
        s_secc_app_parameter[idx].parameter_max_charging_curr = 2500;
        s_secc_app_parameter[idx].parameter_min_charging_curr = 10;

        memset(&s_secc_app_status[idx], 0x00, sizeof(s_secc_app_status[idx]));
    }
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
    if (idx == 1)
    {
        s_secc_create_info[idx].tag = 1;
        s_secc_create_info[idx].hal_handle = secc_hal_one_handle(idx);
        s_secc_create_info[idx].secc_gbt27930_type = OPENCHAOJI_SECC_GBT27930_TYPE_B;

        s_secc_create_info[idx].pilot.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].pilot.hal_handle = s_secc_create_info[idx].hal_handle;
        s_secc_create_info[idx].pilot.secc_gbt27930_type = s_secc_create_info[idx].secc_gbt27930_type;

        s_secc_create_info[idx].session.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.hal_handle = s_secc_create_info[idx].hal_handle;
        s_secc_create_info[idx].session.secc_gbt27930_type = s_secc_create_info[idx].pilot.secc_gbt27930_type;

        s_secc_create_info[idx].session.gbt27930_info.gbt27930_b.dummy = 0;

        s_secc_create_info[idx].session.data_buff.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.data_buff.recv_capacity = 4;

        s_secc_create_info[idx].session.linkage.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.linkage.gbt27930_info.gbt27930_b.can_type	 = OPENCHAOJI_GBT27930_B_CAN_TYPE_20;
        s_secc_create_info[idx].session.linkage.gbt27930_info.gbt27930_b.secc_version = OPENCHAOJI_GBT27930_B_PROTOCOL_VERSION_TYPE_2_0_0;
        s_secc_create_info[idx].session.linkage.tag = s_secc_create_info[idx].tag;
        s_secc_create_info[idx].session.linkage.hal_handle = s_secc_create_info[idx].hal_handle;
        s_secc_create_info[idx].session.linkage.secc_gbt27930_type = s_secc_create_info[idx].pilot.secc_gbt27930_type;

        memset(&s_secc_app_parameter[idx], 0x00, sizeof(s_secc_app_parameter[idx]));
        s_secc_app_parameter[idx].fdc_support_auth[1]       = OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT;
        s_secc_app_parameter[idx].fdc_support_selfcheck[0]  = OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT;
        s_secc_app_parameter[idx].fdc_support_energy[0]     = OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT;
        s_secc_app_parameter[idx].fdc_support_statistics[0] = OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT;

        s_secc_app_parameter[idx].parameter_max_charging_volt = 7500;
        s_secc_app_parameter[idx].parameter_min_charging_volt = 2600;
        s_secc_app_parameter[idx].parameter_max_charging_curr = 2500;
        s_secc_app_parameter[idx].parameter_min_charging_curr = 10;

        s_secc_app_parameter[idx].rfid_auth_m_time = 1; //分钟

        memset(&s_secc_app_status[idx], 0x00, sizeof(s_secc_app_status[idx]));
    }
#endif

    return;
}

void secc_app_init()
{
    OpenChaoJi_os_memeory_init();

    // 设置默认的打印级别, 后续运行时App可以根据实际情况调用此方法修改打印级别以获得不同程度的调试信息
    OpenChaoJi_debug_set_log_level(DEFAULT_DBG_LEVEL
                                // | DBGL_INFO
                                // | DBGL_DEBUG
                                );

    for (int idx = 0; idx < HAL_SIMU_CONNECTOR_NUM; idx++)
    {
        // 厂家首先需要初始化HAL层
        secc_hal_one_init(idx);

        // 创建上下文, 上下文将是后续所有模块通信的唯一句柄
        secc_app_one_init(idx);

        s_secc_context[idx] = OpenChaoJi_secc_create_context(&s_secc_create_info[idx]);
        if (s_secc_context[idx] == NULL)
        {
            continue;
        }
    }
}

void secc_app_term()
{
    for (int idx = 0; idx < HAL_SIMU_CONNECTOR_NUM; idx++)
    {
        secc_hal_one_term(idx);

        if (s_secc_context[idx] != NULL)
        {
            OpenChaoJi_secc_destroy_context(s_secc_context[idx]);
        }
    }

    OpenChaoJi_os_memeory_term();
}



static bool secc_app_one_check_start(int idx)
{
    char file_name[30];
    sprintf(file_name, "/tmp/secc_appstart_%d", idx);

    if (access(file_name, F_OK) == 0)
    {
        remove(file_name);

        secc_hal_one_reset(idx);

        return true;
    }

    return false;
}

static bool secc_app_one_check_stop(int idx)
{
    char file_name[30];
    sprintf(file_name, "/tmp/secc_appstop_%d", idx);

    if (access(file_name, F_OK) == 0)
    {
        remove(file_name);

        return true;
    }

    return false;
}

static int secc_app_read_remove_file(const char * file_name)
{
    FILE *file = fopen(file_name, "r");
    if (!file)
    {
        return -1;
    }

    int level = -1;
    if (fscanf(file, "%d", &level) == 1)
    {
        remove(file_name);
        return level;
    }

    fclose(file);
    remove(file_name);
    return -1;
}

static void secc_app_check_dbg_level()
{
    int level = secc_app_read_remove_file("/tmp/secc_dbg");
    if (level >= 0)
    {
        OpenChaoJi_debug_set_log_level(level);
    }

    return;
}

static void secc_app_check_dgb_module()
{
    int enable = -1;

    enable = secc_app_read_remove_file("/tmp/secc_dbg_transport");
    if (enable >= 0)
    {
        OpenChaoJi_debug_set_log_module_transport((enable > 0)? true : false);
        return;
    }

    enable = secc_app_read_remove_file("/tmp/secc_dbg_dbf");
    if (enable >= 0)
    {
        OpenChaoJi_debug_set_log_module_data_buff((enable > 0)? true : false);
        return;
    }

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
    enable = secc_app_read_remove_file("/tmp/secc_dbg_gbt_b_public");
    if (enable >= 0)
    {
        OpenChaoJi_debug_set_log_module_gbt_b_public((enable > 0)? true : false);
        return;
    }
#endif

    return;
}

void secc_app_service()
{
    // 运行时实时修改打印级别
    secc_app_check_dbg_level();
    secc_app_check_dgb_module();

    for (int idx = 0; idx < HAL_SIMU_CONNECTOR_NUM; idx++)
    {
        if (s_secc_context[idx] != NULL)
        {
            secc_hal_one_service(idx);

            // 检查启动停止
            if (secc_app_one_check_start(idx))
            {
                s_secc_context[idx]->secc_gbt27930_system->app_start_func(s_secc_context[idx], &s_secc_app_parameter[idx]);
            }
            if (secc_app_one_check_stop(idx))
            {
                s_secc_context[idx]->secc_gbt27930_system->app_stop_func(s_secc_context[idx]);
            }

            // 更新实时状态
            s_secc_context[idx]->secc_gbt27930_system->app_get_status_func(s_secc_context[idx], &s_secc_app_status[idx]);

            // 执行serivce
            OpenChaoJi_secc_service(s_secc_context[idx]);
        }
    }
}



void interrupt_emergency_a()
{
    OpenChaoJi_secc_service(s_secc_context[0]);
}

void interrupt_emergency_b()
{
    OpenChaoJi_secc_service(s_secc_context[1]);
}
